package org.jupiter.blog.authentic.handler;

import org.jupiter.blog.common.utils.PasswordUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;

import java.util.Objects;

@Component
public class RsaPasswordAuthenticationProvider implements AuthenticationProvider {

	@Autowired
	private UserDetailsService userDetailsService;

	@Override
	public Authentication authenticate(Authentication authentication) throws AuthenticationException {
		String username = Objects.toString(authentication.getPrincipal(), null);
		String encryptedPassword = Objects.toString(authentication.getCredentials(), null);
		if (username == null || encryptedPassword == null) {
			throw new BadCredentialsException("Missing credentials");
		}

		UserDetails userDetails = userDetailsService.loadUserByUsername(username);
		String storedHash = userDetails.getPassword();
		try {
			String rawPassword = PasswordUtil.decryptPassword(encryptedPassword);
			boolean verified = PasswordUtil.verifyPassword(rawPassword, storedHash);
			if (!verified) {
				throw new BadCredentialsException("Bad credentials");
			}
			return new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
		} catch (BadCredentialsException e) {
			throw e;
		} catch (Exception e) {
			throw new BadCredentialsException("Password verification failed", e);
		}
	}

	@Override
	public boolean supports(Class<?> authentication) {
		return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
	}
}


